package com.sisgesbyte.services.proyeccion;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.inject.Inject;

import com.sisgesbyte.common.ConstModAdministracion;
import com.sisgesbyte.common.ConstProyeccion;
import com.sisgesbyte.common.ConstantesInternasSistema;
import com.sisgesbyte.common.Validaciones;
import com.sisgesbyte.dao.beanDao.FiltrosBean;
import com.sisgesbyte.dao.beanDao.FiltrosSQLBean;
import com.sisgesbyte.dao.proyeccion.MantBandaProyeccionDao;
import com.sisgesbyte.dao.proyeccion.MantProyeccionZonaDao;
import com.sisgesbyte.dao.proyeccion.MantProyeccionZonaDetalleDao;
import com.sisgesbyte.dao.ventas.ConsultaVentasDao;
import com.sisgesbyte.data.entity.proyeccion.BandaProyeccionEntity;
import com.sisgesbyte.data.entity.proyeccion.ProyeccionZonaDetalleEntity;
import com.sisgesbyte.data.entity.proyeccion.ProyeccionZonaEntity;
import com.sisgesbyte.data.entity.ventas.VentasEntity;
import com.sisgesbyte.services.administracion.bean.ZonaBean;
import com.sisgesbyte.services.proyeccion.bean.AvanceProyeccionProductResponse;
import com.sisgesbyte.services.proyeccion.bean.AvanceProyeccionZonaResponse;
import com.sisgesbyte.services.proyeccion.bean.FiltroProductoZonaBean;
import com.sisgesbyte.services.proyeccion.bean.AvanceVentaProductosBean;
import com.sisgesbyte.services.proyeccion.bean.ProyeccionZonaBean;
import com.sisgesbyte.services.ventas.MantenimientoZona;
import com.sisgesbyte.services.ventas.bean.ZonaListaResponse;

@Stateless
public class ProyeccionZonaPorPeriodoServiceImpl implements ProyeccionZonaPorPeriodoService {

	@EJB
	private MantProyeccionZonaDao mantProyeccionZonaDao;
	@EJB
	private ConsultaVentasDao consultaVentasDao;
	@EJB
	private MantenimientoZona mantenimientoZona;
	@Inject
	private Validaciones validaciones;
	@EJB
	private MantBandaProyeccionDao mantBandaProyeccionDao;
	@EJB
	private MantProyeccionZonaDetalleDao mantProyeccionZonaDetalleDao;
	
	@Override
	public AvanceProyeccionZonaResponse listaAvanceZonas(String codTransaccion,int idPeriodo,int idZona) {
		
		String mensajeTransaccionMetodo = "[listaAvanceZonas idTx=" + codTransaccion + "] - ";
		AvanceProyeccionZonaResponse response = new AvanceProyeccionZonaResponse();
		
		List<ProyeccionZonaEntity> listaProyeccionZonas =null;
		try{
			FiltrosSQLBean filtros = null;
			if(idZona > 0){
				 filtros = new FiltrosSQLBean();
				 List<FiltrosBean> listaFiltros = new ArrayList<FiltrosBean>();
				 FiltrosBean filtroCampos = new FiltrosBean();
				 List<String> campos = new ArrayList<String>();
				 campos.add("pz.zona_id");
				 filtroCampos.setCampos(campos);
				 filtroCampos.setOperador("=");
				 listaFiltros.add(filtroCampos);
				 List<Object> valores = new ArrayList<Object>();
				 valores.add(idZona);
				 filtros.setListaFiltros(listaFiltros);
				 filtros.setListaValores(valores);
			}
			//1.- obtenemos las proyecciones  de las zonas
			listaProyeccionZonas = mantProyeccionZonaDao.listaProyeccionZona(filtros);
			
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al listar las proyeccion de zonas de  BD " + e);
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
			return response;
		}
		
		if(listaProyeccionZonas.size() > 0){
			
			List<VentasEntity> listaVentaZona = null;
			try{
				FiltrosSQLBean filtros = null;
				if(idZona > 0){
					 filtros = new FiltrosSQLBean();
					 List<FiltrosBean> listaFiltros = new ArrayList<FiltrosBean>();
					 FiltrosBean filtroCampos = new FiltrosBean();
					 List<String> campos = new ArrayList<String>();
					 campos.add("zona_id");
					 filtroCampos.setCampos(campos);
					 filtroCampos.setOperador("=");
					 listaFiltros.add(filtroCampos);
					 List<Object> valores = new ArrayList<Object>();
					 valores.add(idZona);
					 filtros.setListaFiltros(listaFiltros);
					 filtros.setListaValores(valores);
				}
				//2.- obtenemos las ventas de todas las zonas
				listaVentaZona = consultaVentasDao.listaVentasDetalle(filtros);
			}catch(Exception e){
				System.out.println(mensajeTransaccionMetodo + "Hubo un error en BD al listar las ventas de las zonas  " + e);
				response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
				response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
				return response;
			}
			
			if(listaVentaZona.size() > 0){
				
				ZonaListaResponse zonas = null;
				try{
					 FiltrosSQLBean filtros= new FiltrosSQLBean();
					 List<FiltrosBean> listaFiltros = new ArrayList<FiltrosBean>();
					 List<Object> valores = new ArrayList<Object>();
					//filtro por estado
					 FiltrosBean filtroActive = new FiltrosBean();
					 List<String> campoActive = new ArrayList<String>();
					 campoActive.add("active");
					 filtroActive.setCampos(campoActive);
					 filtroActive.setOperador("=");
					 listaFiltros.add(filtroActive);
					 valores.add(true);
					
					 if(idZona > 0){
						 //filtro por idZona
						 FiltrosBean filtroId = new FiltrosBean();
						 List<String> campoId = new ArrayList<String>();
						 campoId.add("id");
						 filtroId.setCampos(campoId);
						 filtroId.setOperador("=");
						 listaFiltros.add(filtroId);
						 valores.add(idZona);
					}
					 
					 filtros.setListaFiltros(listaFiltros);
					 filtros.setListaValores(valores);
					//3.- consultamos la lista de zonas
					zonas = mantenimientoZona.listaZonas(codTransaccion, filtros);
				}catch(Exception e){
					System.out.println(mensajeTransaccionMetodo + "Hubo un error en BD al listar las zonas  " + e);
					response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDT);
					response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDT);
					return response;
				}
				
				if(zonas.getCodigoRespuesta().equalsIgnoreCase(ConstantesInternasSistema.CODIGO_EXITO)){
					
					List<ProyeccionZonaBean> lZonas = new ArrayList<ProyeccionZonaBean>();

					//recorremos las zonas encontradas
					for(ZonaBean ls : zonas.getListaZonas()){
						
						ProyeccionZonaBean proyZona = new ProyeccionZonaBean();
						
						BigDecimal montoTotalProyeccionGeneral = BigDecimal.ZERO;
						BigDecimal montoTotalProyeccionPeriodo = BigDecimal.ZERO;
						String bandaGeneral = validaciones.validarCamposString(ls.getBanda_proyeccion());
						String bandaPeriodo ="";
						boolean encontro = false;
						//recorremos las proyecciones de cada zona
						for(ProyeccionZonaEntity proyeccion : listaProyeccionZonas){
							if(ls.getId() == proyeccion.getZona_id()){
								encontro = true;
								montoTotalProyeccionGeneral = montoTotalProyeccionGeneral.add(proyeccion.getMonto_periodo());
							}
							if((ls.getId() == proyeccion.getZona_id()) && (proyeccion.getPeriodo_id() == idPeriodo) ){
								montoTotalProyeccionPeriodo = montoTotalProyeccionPeriodo.add(proyeccion.getMonto_periodo());
								bandaPeriodo = proyeccion.getBanda_periodo();
								//capturamos el codigo de la proyeccion por zona
								proyZona.setIdProyeccionZona(proyeccion.getId());
							}
						}
						BigDecimal montoTotalVentaGeneral = BigDecimal.ZERO;
						BigDecimal montoTotalVentaPeriodo = BigDecimal.ZERO;
						//validamos si la zona tiene proyeccion asignada
						if(encontro){
							//recorremos las ventas de cada zona
							for(VentasEntity ventasZona : listaVentaZona){
								if(ls.getId() == ventasZona.getZona_id()){
									montoTotalVentaGeneral = montoTotalVentaGeneral.add(ventasZona.getTotal());
								}
								if((ls.getId() == ventasZona.getZona_id()) && (ventasZona.getPeriodo_id() == idPeriodo) ){
									montoTotalVentaPeriodo = montoTotalVentaPeriodo.add(ventasZona.getTotal());
								}
							}
							BigDecimal porcentajeAvanceGeneral= BigDecimal.ZERO;
							BigDecimal porcentajeAvancePeriodo = BigDecimal.ZERO;
							
							try{
								porcentajeAvanceGeneral = montoTotalVentaGeneral.divide(montoTotalProyeccionGeneral,4, RoundingMode.CEILING);
							}catch(Exception e){
								System.out.println("Error al obtener  porcentajeAvanceGeneral " + e);
								porcentajeAvanceGeneral= BigDecimal.ZERO;
							}
							
							try{
								porcentajeAvancePeriodo = montoTotalVentaPeriodo.divide(montoTotalProyeccionPeriodo,4, RoundingMode.CEILING);
							}catch(Exception e){
								System.out.println("Error al obtener  porcentajeAvancePeriodo " + e);
								porcentajeAvancePeriodo = BigDecimal.ZERO;
							}
							//obtenemos el color de la banda General
							String colorbandaGeneral = colorBanda(bandaGeneral,porcentajeAvanceGeneral,1);
							String colorbandaPeriodo = colorBanda(bandaPeriodo,porcentajeAvancePeriodo,1);
							//codigo de la zona
							proyZona.setIdZona(ls.getId());
							proyZona.setZona(validaciones.validarCamposString(ls.getCodigo()));
							proyZona.setAvanceMontoGeneral(montoTotalVentaGeneral);
							proyZona.setAvanceMontoPeriodo(montoTotalVentaPeriodo);
							proyZona.setProyeccionMontoGeneral(montoTotalProyeccionGeneral);
							proyZona.setProyeccionMontoPeriodo(montoTotalProyeccionPeriodo);
							proyZona.setAvancePorcentajeGeneral(porcentajeAvanceGeneral.multiply(new BigDecimal(100)));
							proyZona.setAvancePorcentajePeriodo(porcentajeAvancePeriodo.multiply(new BigDecimal(100)));
							proyZona.setColorBandaGeneral(colorbandaGeneral);
							proyZona.setColorBandaPeriodo(colorbandaPeriodo);
							
							lZonas.add(proyZona);
						}
					}
					response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
					response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
					response.setListaAvanceProyeccionZona(lZonas);
					
				}else{
					System.out.println("No se encontraron Datos al listar las zonas");
					response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
					response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
					return response;
				}
			}else{
				System.out.println("No se encontraron Datos en las ventas por zonas");
				response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
				response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
				return response;
			}
			
			
		}else{
			System.out.println("No se encontraron Datos en la proyecciones por zona ");
			response.setCodigoRespuesta(ConstProyeccion.PROYECCION_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstProyeccion.PROYECCION_LISTAR_MSJ_IDF);
		}
		
		return response;
	}

	public String colorBanda(String codBanda,BigDecimal porcentaje, int tipoColor){
		String color ="";
			try{
				
			List<BandaProyeccionEntity> listaBandas = null;
			 try{
				 FiltrosSQLBean cadenaFiltros = new FiltrosSQLBean();
				 List<FiltrosBean> listaFiltros = new ArrayList<FiltrosBean>();
				 FiltrosBean filtroCampos = new FiltrosBean();
				 List<String> campos = new ArrayList<String>();
				 campos.add("codigo");
				 filtroCampos.setCampos(campos);
				 filtroCampos.setOperador("=");
				 listaFiltros.add(filtroCampos);
				 List<Object> valores = new ArrayList<Object>();
				 valores.add(codBanda);
				 cadenaFiltros.setListaFiltros(listaFiltros);
				 cadenaFiltros.setListaValores(valores);
				 listaBandas = mantBandaProyeccionDao.listaBandasProyeccion(cadenaFiltros);
			}catch(Exception e){
				System.out.println("Error al Obtener las bandas: " + e);
			}
			 List<BigDecimal> bandas = new ArrayList<BigDecimal>();
			 if(listaBandas.size() > 0 && listaBandas!= null){
				 BigDecimal suma = BigDecimal.ZERO;
				 for(BandaProyeccionEntity ls : listaBandas){
					 suma = suma.add(ls.getPorcentaje());
					 bandas.add(suma);
				 }
			 }
		
			int i=0;
			for(BigDecimal ls :bandas ){
				
				++i;
				if(porcentaje.compareTo(ls) == -1){
					break;
				}
			}
			
			if(tipoColor ==1){
				switch(i){
				case 1:
					color = "C84545";
					break;
				case 2:
					color = "CFF30A";
					break;
				case 3:
					color = "02F327";
					break;
				}
			}
			
			if(tipoColor ==2){
				switch(i){
				case 1:
					color = "rojo";
					break;
				case 2:
					color = "amarillo";
					break;
				case 3:
					color = "verde";
					break;
				}
			}
			
			}catch(Exception e){
				System.out.println("Error en el proceso para capturar el color de la Banda - " + e);
				color="";
			}
			return color;
		}

	@Override
	public AvanceProyeccionProductResponse listaProductosZona( String codTransaccion, FiltroProductoZonaBean filtros) {
			
		String mensajeTransaccionMetodo = "[listaProductosZona idTx=" + codTransaccion + "] - ";
		AvanceProyeccionProductResponse response = new AvanceProyeccionProductResponse();
		
		if(filtros.getIdPeriodo() < 1){
			System.out.println(mensajeTransaccionMetodo+" Es necesario el codigo del periodo");
			response.setIdTransaccion(codTransaccion);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_LISTAR_COD_IDF);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_LISTAR_MSJ_IDF.replace("msj", mensajeTransaccionMetodo));
			return response;
		}
		
		List<ProyeccionZonaDetalleEntity> proyProducto = null; 
		try{
			FiltrosSQLBean filtro = new FiltrosSQLBean();
			List<FiltrosBean> listaFiltros = new ArrayList<FiltrosBean>();
			List<Object> valores = new ArrayList<Object>();
			//filtro por periodo
			FiltrosBean filtroPeriodo = new FiltrosBean();
			List<String> campoPeriodo = new ArrayList<String>();
			campoPeriodo.add("pz.periodo_id");
			filtroPeriodo.setCampos(campoPeriodo);
			filtroPeriodo.setOperador("=");
			listaFiltros.add(filtroPeriodo);
			valores.add(filtros.getIdPeriodo());
			
			if(filtros.getIdZona() > 0){
				//filtro por zona
				FiltrosBean filtroZona = new FiltrosBean();
				List<String> campoZona = new ArrayList<String>();
				campoZona.add("pz.zona_id");
				filtroZona.setCampos(campoZona);
				filtroZona.setOperador("=");
				listaFiltros.add(filtroZona);
				valores.add(filtros.getIdZona());
			}
			filtro.setListaFiltros(listaFiltros);
			filtro.setListaValores(valores);
			filtro.setCampoOrden("p.producto");
			filtro.setTipoOrden("asc");
			//1.-obtenemos la proyeccion de los productos
			proyProducto = mantProyeccionZonaDetalleDao.listaProyeccionZonaDetalle(filtro);
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al Tratar de obtener la proyeccion de los productos" +e);
			response.setCodigoRespuesta(ConstModAdministracion.MANT_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_LISTAR_MSJ_IDT.replace("msj", mensajeTransaccionMetodo));
			return response;
		}
		List<VentasEntity> ventasProducto =null;
		try{
			FiltrosSQLBean filtro = new FiltrosSQLBean();
			List<FiltrosBean> listaFiltros = new ArrayList<FiltrosBean>();
			List<Object> valores = new ArrayList<Object>();
			//filtro por periodo
			FiltrosBean filtroPeriodo = new FiltrosBean();
			List<String> campoPeriodo = new ArrayList<String>();
			campoPeriodo.add("periodo_id");
			filtroPeriodo.setCampos(campoPeriodo);
			filtroPeriodo.setOperador("=");
			listaFiltros.add(filtroPeriodo);
			valores.add(filtros.getIdPeriodo());
			
			if(filtros.getIdZona() > 0){
				//filtro por zona
				FiltrosBean filtroZona = new FiltrosBean();
				List<String> campoZona = new ArrayList<String>();
				campoZona.add("zona_id");
				filtroZona.setCampos(campoZona);
				filtroZona.setOperador("=");
				listaFiltros.add(filtroZona);
				valores.add(filtros.getIdZona());
			}
			filtro.setListaFiltros(listaFiltros);
			filtro.setListaValores(valores);
			filtro.setCampoOrden("producto_id");
			filtro.setTipoOrden("asc");
			//2.-obtenemos las ventas de los productos 
			ventasProducto =consultaVentasDao.listaVentasDetalle(filtro);
		}catch(Exception e){
			System.out.println(mensajeTransaccionMetodo + "Hubo un error al Tratar de obtener la ventas de los productos " +e.getMessage());
			response.setCodigoRespuesta(ConstModAdministracion.MANT_LISTAR_COD_IDT);
			response.setMensajeRespuesta(ConstModAdministracion.MANT_LISTAR_MSJ_IDT.replace("msj", mensajeTransaccionMetodo));
			return response;
		}
		List<AvanceVentaProductosBean> listaProductos = new ArrayList<AvanceVentaProductosBean>();
		//recorremos las proyeccion de los productos
		for(ProyeccionZonaDetalleEntity proyeccion :proyProducto){
			AvanceVentaProductosBean bean = new AvanceVentaProductosBean();
			
			BigDecimal avanceProducto = BigDecimal.ZERO;
			for(VentasEntity ventas : ventasProducto){
				//capturamos las ventas por el codigo de producto
				if(proyeccion.getProducto_id()==ventas.getProducto_id()){
					avanceProducto = avanceProducto.add(ventas.getCantidad());
				}
			}
			
			BigDecimal porcentajeAvancePeriodo= BigDecimal.ZERO; 
			try{
				//calculamos el porcentaje de avance periodo
				porcentajeAvancePeriodo = avanceProducto.divide(proyeccion.getCantidad_proyectada(),4, RoundingMode.CEILING);
			}catch(Exception e){
				System.out.println("Error al calcular porcentaje - "+e );
				porcentajeAvancePeriodo= BigDecimal.ZERO; 
			}
			
			String color = colorBanda(validaciones.validarCamposString(proyeccion.getCodigo_banda()), porcentajeAvancePeriodo,2);
			
			bean.setAvancePorcentaje(porcentajeAvancePeriodo.multiply(new BigDecimal(100)));
			bean.setAvanceProducto(avanceProducto);
			bean.setCategoriaProducto(proyeccion.getCategoria_producto());
			bean.setCategoriaProductoId(proyeccion.getCategoria_producto_id());
			bean.setColorBanda(color);
			bean.setCodProd(validaciones.validarCamposString(proyeccion.getCod_prod()));
			bean.setId(proyeccion.getId());
			bean.setMarca(validaciones.validarCamposString(proyeccion.getMarca()));
			bean.setMarcaId(proyeccion.getMarca_id());
			bean.setPeriodoId(proyeccion.getPeriodo_id());
			bean.setProducto(validaciones.validarCamposString(proyeccion.getProducto()));
			bean.setProductoId(proyeccion.getProducto_id());
			bean.setProyeccionProducto(proyeccion.getCantidad_proyectada());
			bean.setProyeccionZonaId(proyeccion.getProyeccion_zona_id());
			bean.setZonaId(proyeccion.getZona_id());
			listaProductos.add(bean);
		}
		response.setIdTransaccion(codTransaccion);
		response.setCodigoRespuesta(ConstantesInternasSistema.CODIGO_EXITO);
		response.setMensajeRespuesta(ConstantesInternasSistema.MENSAJE_EXITO);
		response.setListaProductosZonas(listaProductos);
		return response;
	}
			
}
